/**
 ****************************************************************************************************
 * @file        Button.c
 * @author      Le Tang
 * @email       247022864@qq.com
 * @version     V1.0
 * @date        2020-01-01
 * @brief       按键检测
 ****************************************************************************************************
 * @attention
 *
 * 测试平台:STM32H743IIT6,FreeRTOS
 *
 * 声明:此程序只用作学习，未经许可用作商业用途，必追究责任！
 *
 * 修改说明
 * V1.0 20200101发布
 * 第一次发布
 *
 ****************************************************************************************************
 */
 
#ifndef __BSP_BUTTON_H__
#define __BSP_BUTTON_H__

/**
*****************************************************************************************************
* 包含头文件
*****************************************************************************************************
*/

#include <stdint.h>
#include <string.h>
#include "gpio.h"

/***************************************************************************************************/

/**
*****************************************************************************************************
* 宏定义
*****************************************************************************************************
*/

/***************************************************************************************************/

#define EVENT_CB(ev) do{handle->cb(ev);}while(0)

#define TICKS_INTERVAL 10  // ms 按键扫描的时间
#define DEBOUNCE_TICKS 1  // 消抖时间,DEBOUNCE_TICKS个TICKS_INTERVAL时间
#define SHORT_TICKS (300 / TICKS_INTERVAL) //短按超时时间
#define LONG_TICKS (1000 / TICKS_INTERVAL) //长按超时时间

/***************************************************************************************************/

/***************************************************************************************************/

/**
*****************************************************************************************************
* 定义枚举类型
*****************************************************************************************************
*/
typedef enum
{
	BTN_UNPRESS = 0,		 //按键未按下
	BTN_PRESSED = 0x01,		 //按键被按下
	PRESS_DOWN = 0x02,		 //按键按下，每次按下都触发
	PRESS_UP = 0x04,		 //按键弹起，每次松开都触发
	PRESS_REPEAT = 0x08,	 //重复按下触发，变量repeat计数连击次数
	SINGLE_CLICK = 0x10,	 //单击按键事件
	DOUBLE_CLICK = 0x20,	 //双击按键事件
	LONG_RRESS_START = 0x40, //达到长按时间阈值时触发一次
	LONG_PRESS_HOLD = 0x80,	 //长按期间一直触发
	number_of_event = 9,
}PressEvent;

/***************************************************************************************************/

/**
*****************************************************************************************************
* 定义结构体类型
*****************************************************************************************************
*/
typedef struct Button
{
	struct Button *next;
	uint16_t ticks;
	uint8_t event;
	uint8_t repeat : 4;
	uint8_t state : 3;
	uint8_t debounce_cnt : 3;
	uint8_t button_level : 1;
	uint8_t (*hal_button_Level)(void);
	void (*cb)(PressEvent);
}Button;

/***************************************************************************************************/

/**
*****************************************************************************************************
* 全局变量声明
*****************************************************************************************************
*/

typedef void (*BtnCallback)(PressEvent event);

extern Button *head_handle;

/***************************************************************************************************/

/**
*****************************************************************************************************
* static函数声明
*****************************************************************************************************
*/


/***************************************************************************************************/

/**
*****************************************************************************************************
* 全局函数声明
*****************************************************************************************************
*/

void button_init(void(*button_init_callback)(void));
int8_t button_start(Button* handle);
void button_stop(Button *handle);
void button_ticks(void);
PressEvent get_button_event(Button *handle);
void button_attach(Button *handle,uint8_t (*pin_level)(),BtnCallback cb,PressEvent event);

/***************************************************************************************************/

#endif

/****************************************************************************************************
  End Of File
****************************************************************************************************/

